﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Krist_em_up.Components;
using Microsoft.Xna.Framework;
using Krist_em_up.Music;
using Microsoft.Xna.Framework.Media;
using Krist_em_up.Interface;
using Microsoft.Xna.Framework.Graphics;
using ZoomEngine.Animation;
using Krist_em_up.i18n;
using System.Globalization;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Input;
using Krist_em_up.Characters;
using Microsoft.Xna.Framework.GamerServices;


namespace Krist_em_up
{
    public class GameStateManager : Game
    {
        protected Stack<GameScreen> gameScreens;
        protected Clavier kb;
        public GraphicsDeviceManager graphics;

        protected Song menuSong;

        protected TimeSpan UpdateDelay;

        public Settings.Settings settings;

        protected ClockManager clockManager;

        public ClockManager ClockManager
        {
            get { return clockManager; }
            protected set { clockManager = value; }
        }
        public GameStateManager()
            : base()
        {
            graphics = new GraphicsDeviceManager(this);
            gameScreens = new Stack<GameScreen>();
            clockManager = new ClockManager(this);
            Menu menu = new Menu(this);

            //Uncomment to mettre le jeu en engliche
            //Strings.Culture = new CultureInfo("en");

            gameScreens.Push(menu);
        }
        protected override void Initialize()
        {

            graphics.PreferredBackBufferWidth = GraphicsDevice.DisplayMode.Width;
            graphics.PreferredBackBufferHeight = GraphicsDevice.DisplayMode.Height;
            //graphics.IsFullScreen = true;
            Viewport v = new Viewport();
            v.Width = graphics.PreferredBackBufferWidth;
            v.Height = graphics.PreferredBackBufferHeight;
            GraphicsDevice.Viewport = v;
            graphics.ApplyChanges();


            //GraphicsAdapter.DefaultAdapter.SupportedDisplayModes;
            kb = new Clavier(this);
            Components.Add(kb);
            Content.RootDirectory = "Content";
            IsMouseVisible = true;
            Sounds.Initialize(Content);

            settings = new Settings.Settings();
            settings = settings.FromFile();

            foreach (GameScreen screen in gameScreens)
            {
                screen.Initialize();
            }

            Components.Add(new GamerServicesComponent(this));
            base.Initialize();



        }
        protected override void LoadContent()
        {
            foreach (GameScreen screen in gameScreens)
            {
                screen.LoadContent();
            }
            base.LoadContent();

            //Start menu music
            try
            {
                menuSong = Content.Load<Song>("Song/menu");
                MediaPlayer.Play(menuSong);
                MediaPlayer.IsRepeating = true;
            }
            catch { }
        }
        protected override void UnloadContent()
        {
            while (gameScreens.Count > 0)
            {
                gameScreens.Pop().UnloadContent();
            }
            base.UnloadContent();
        }
        protected override void Update(GameTime gameTime)
        {
            if (UpdateDelay <= TimeSpan.Zero)
            {
                if (gameScreens.Count == 0)
                    this.Exit();
                else
                {
                    gameScreens.First().Update(gameTime);
                    if (gameScreens.First() is Credits)
                    {
                        Credits temp = (Credits)gameScreens.First();
                        if (temp.exit)
                        {
                            gameScreens.Pop();
                            gameScreens.Pop();
                        }
                    }
                    if (gameScreens.First() is Kristemup)
                    {
                        Kristemup k = (Kristemup)gameScreens.First();
                        foreach (Kris kris in k.tabKris)
                        {
                            if (kris.reachEnd)
                            {
                                if (k.level == 3)
                                {
                                    gameScreens.Pop();
                                    MediaPlayer.Stop();
                                    Credits c;
                                    c = new Credits(this);
                                    c.Initialize();
                                    c.LoadContent();
                                    gameScreens.Push(c);
                                    ResetDelay();
                                    break;
                                }
                                else
                                {
                                    Kristemup temp = k;
                                    gameScreens.Pop();
                                    if (k.tabKris.Length == 2)
                                        play(temp.level + 1, temp.score, temp.tabKris[0].Hp, temp.tabKris[0].Lives, temp.tabKris[1].Hp, temp.tabKris[1].Lives);
                                    else
                                        play(temp.level + 1, temp.score, temp.tabKris[0].Hp, temp.tabKris[0].Lives);
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                UpdateDelay -= gameTime.ElapsedGameTime;
            }
            clockManager.Update(gameTime);
            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            graphics.GraphicsDevice.Clear(Color.Black);
            Stack<GameScreen> visibles = new Stack<GameScreen>();
            foreach (GameScreen s in gameScreens)
            {
                visibles.Push(s);
                if (!s.IsPopup)
                    break;
            }
            while (visibles.Count > 0)
            {
                visibles.Pop().Draw(gameTime);
            }
            base.Draw(gameTime);
        }

        public Clavier getClavier()
        {
            return kb;
        }

        public void play(int level,int score, int hpJ1, int vieJ1)
        {
            MediaPlayer.Stop();
            Kristemup k;
            k = new Kristemup(this, level,score);
            k.Initialize();
            k.LoadContent();
            k.SetPlayerControls(settings.PlayerOne);
            gameScreens.Push(k);
            ResetDelay();
            k.Launch();
            k.tabKris[0].Hp = hpJ1;
            k.tabKris[0].Lives = vieJ1;
        }

        public void play(int level, int score,int hpJ1, int vieJ1, int hpJ2, int vieJ2)
        {
            MediaPlayer.Stop();
            Kristemup k;
            k = new KristemupMulti(this, level,score);
            k.Initialize();
            k.LoadContent();
            k.SetPlayerControls(settings.PlayerOne);
            gameScreens.Push(k);
            ResetDelay();
            k.Launch();
            k.tabKris[0].Hp = hpJ1;
            k.tabKris[1].Hp = hpJ2;
            k.tabKris[0].Lives = vieJ1;
            k.tabKris[1].Lives = vieJ2;
        }

        internal void Options()
        {
            OptionsMenu OpMenu = new OptionsMenu(this, settings.PlayerOne, settings.PlayerTwo);
            OpMenu.Initialize();
            gameScreens.Push(OpMenu);
            ResetDelay();
        }

        internal void LeaveOptMenu()
        {
            gameScreens.Pop();
            gameScreens.First().Reset();
            ResetDelay();
        }

        public void SetControls(ControlsConfig ctrls1, ControlsConfig ctrls2)
        {
            settings.PlayerOne = ctrls1;
            settings.PlayerTwo = ctrls2;
            settings.SaveIntoFile();
        }

        internal void LeaveCurrentScreen()
        {
            gameScreens.Pop();

            gameScreens.First().Reset();
            ResetDelay();
        }

        internal void SelectPlayMode()
        {
            gameScreens.Push(new NbPlayerMenu(this));
            ResetDelay();
        }

        internal void PauseGame()
        {
            gameScreens.Push(new Pause(this));
            ResetDelay();
        }

        public void LeavePauseMenu(object sender, EventArgs e)
        {
            gameScreens.Pop();
            gameScreens.First().Reset();
            ResetDelay();
        }
        public void LeaveGameFromPause(object sender, EventArgs e)
        {
            GameScreen current = gameScreens.Pop();
            while (!(current is Menu))
            {
                current = gameScreens.Pop();
            }
            current.Reset();
            gameScreens.Push(current);
            ResetDelay();
        }
        public void MenuOptions(object sender, EventArgs e)
        {
            Options();
            ResetDelay();
        }

        protected void ResetDelay()
        {
            UpdateDelay = new TimeSpan(0, 0, 0, 0, 300);
        }
    }
}